home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / SeqPups / appsrc / drawtree.src / interface.c < prev    next >
Text File  |  1996-07-05  |  14KB  |  549 lines

  1. /* stderr */
  2.  
  3. /* Interface
  4.    By Sean T. Lamont
  5.    For use with the Macntosh version of the Phylogeny Inference Package,
  6.    version 3.5c. (c) Copyright 1992 by Joseph Felsenstein.
  7.    Permission is granted to copy and use this program provided no fee is
  8.    charged for it and provided that this copyright notice is not removed.
  9.  
  10.    This file defines a 2-window environment which replicates many
  11.    of the standard c I/O functions (puts, printf,gets,scanf)
  12.    in a maclike environment, with a scrollback buffer.  This
  13.    is necessary because of the very weak implementation of IO under
  14.    straight C, and the difficulty of using separate windows. It also
  15.    adds the ability to "quit" out of an application while it is running,
  16.    and some very basic point-and-click interface type of stuff on the
  17.    screen.
  18.  
  19.    Functions you need to know how to use:
  20.    macsetup(char *name):  initializes the interface, brings up a window of
  21.                           the name of the argument, for I/O.
  22.    macprintf(char *string,arg,arg):  like printf but into the window
  23.    macgets(char *string);            like puts   but into the window
  24.    macscanf(char *string, arg,arg)   like scanf  but from the window
  25.    macgets (char *string,arg,arg)    like gets but from the window.
  26.  
  27.    It is recommended that you include "interface.h" file, which sets
  28.    up these #define's for you (IE all calls to scanf will call
  29.    macscanf, etc.)
  30.  
  31.   textmode(); makes the current drawing window the text window
  32.    gfxmode(); makes the current drawing window the gfx window,
  33.               unhides the graphics window.
  34.  
  35.   eventloop():  process mouse events, menus, etc., and wait for
  36.                 "go away" event.  You are implicitly doing this\
  37.                  when you run macgets/macscanf.  If you want to query
  38.                  the event handler during non-IO periods of time this
  39.                  would be what to call (or alternatively, printf("");
  40.  */
  41.  
  42.  
  43. #include <stdarg.h>
  44. #include <stdio.h>
  45. #include "interface.h"
  46.  
  47. #define SCROLLLINES 200
  48.  
  49. #define SCROLLCOLUMNS 80
  50. #define SCROLLMEM    17000
  51. #define LINEDEPTH  (int)12
  52. #define PAGELINES (int)(260 / 12)
  53. #define TEXT 0
  54. #define GFX 1
  55.  
  56. /* Global variables, most for use with input/output */
  57. int disablescrollback = 0;
  58. int mode = TEXT;
  59. WindowPtr gfxWindow;
  60. WindowPtr textWindow;
  61. MenuHandle appleMenu,fileMenu;
  62. char *lines[SCROLLLINES]; /* the scrollback buffer */
  63. int cursorx=0; /* the current x position that the text cursor is at */
  64. int cursory=0; /* the current y position that the text cursor is at */
  65. int numlines_=0;/* the next place we put a new line.                 */
  66. int memptr=0;  /* the next place in our space we get memory from.   */
  67. int linectr=0;
  68. /*char *memory; */
  69. char memory[SCROLLMEM]; /*?? << dgg, save data seg for thinkc */
  70.  
  71. char line[256];/* used to accumulate output before newlines.        */
  72. Rect textBounds = {40,5,300,500}; /* position of window 1          */
  73. Rect gfxBounds  = {0,0,350,500}; /* position of window 2          */
  74. Rect textrect   = {0,0,260,479};   /* region to clear within window */
  75. Rect barBounds  = {0,480,260,495}; /* position of the scroll bar    */
  76. RgnHandle rgn;                     /* used by scrollrect            */
  77. ControlHandle bar;                 /* this is the scrollbar control */
  78. int lasttop=0;                     /* used by update / scrollrect   */
  79. char inputs[256];                  /* used by the input routines    */
  80. int  inputcount = 0;               /* offset into the string.       */
  81. int  collect    = false;           /* boolean: collect chars?       */
  82.  
  83. void macsetup(tname,gname)
  84. char *tname,*gname;
  85. {
  86. static char buf1[128];
  87. static char buf2[128];
  88.  
  89. strcpy(buf1+1,tname);
  90. strcpy(buf2+1,gname);
  91. buf1[0]=strlen(tname);
  92. buf2[0]=strlen(gname);
  93. MaxApplZone();
  94. #ifdef __MWERKS__
  95. InitGraf(&qd.thePort);
  96. #else
  97. InitGraf(&thePort);
  98. #endif
  99. InitFonts();
  100. FlushEvents(everyEvent,0);
  101. InitWindows();
  102. InitMenus();
  103. TEInit();
  104. InitDialogs(0L);
  105. InitCursor();
  106. /* memory= (char*)malloc(SCROLLMEM); */
  107. textWindow = NewWindow(0L,&textBounds,(ConstStr255Param)buf1,true,documentProc,
  108.             (WindowPtr) -1L, true,0);
  109. gfxWindow = NewWindow(0L,&gfxBounds,(ConstStr255Param)buf2,false,noGrowDocProc,
  110.             (WindowPtr) -1L, true,0);
  111. rgn=NewRgn();
  112. SetPort(textWindow);
  113. bar=NewControl(textWindow,&barBounds,(ConstStr255Param)"",true,0,0,
  114.                0,scrollBarProc,0);
  115. InsertMenu(appleMenu=NewMenu(1,"\p\024"),0);     /* add apple menu  */
  116. InsertMenu(fileMenu=NewMenu(2,"\pFile"),0);      /* add file menu   */
  117. TextFont(courier);
  118. TextSize(10);
  119. DrawMenuBar();
  120. AppendMenu(fileMenu,"\pQuit/Q");
  121. AddResMenu(appleMenu, 'DRVR');
  122. macprintf("\n");
  123. }
  124.  
  125.  
  126. void queryevent()
  127. {
  128. int status;
  129. status=handleevent();
  130. if (status <= 0)
  131.      process_window_closure(status);
  132. }
  133.  
  134. void eventloop()
  135. {
  136. int status;
  137.  
  138. while (1){
  139.     status=handleevent();
  140. if (status <= 0)
  141.         process_window_closure(status);  }
  142. }
  143.  
  144.  
  145. process_window_closure(status)
  146. int status;
  147. {
  148. if (status == -1){
  149.          CloseWindow(gfxWindow);   /* "Close main window", so run all the */
  150.         CloseWindow(textWindow);  /* cleanup stuff.                      */
  151.         DisposeRgn(rgn);
  152. #undef exit
  153.         exit(0);
  154. #define exit(status) eventloop()
  155. }
  156. else if (status == 0)
  157.    HideWindow(gfxWindow);}
  158.  
  159.  
  160.  
  161. int handleevent()
  162. {
  163. pascal void scroll();
  164. char pstring[256];
  165. OSErr res;
  166. EventRecord ev;
  167. WindowPtr win;
  168. ControlHandle ctrl;
  169. short menuid,menuitem;
  170. Point MouseLoc;
  171. long menu,i;
  172. int cx,cy;
  173. int PathRefNum;
  174. long  count=80;
  175. SFReply fileinfo;
  176. char c,pasteword[64];
  177. Str255 name;
  178. GrafPtr savePort;
  179. FILE *fp;
  180. Rect drect;
  181. Rect      rect  = {0,0,1000,1000};   /* the limit for dragging windows */
  182. int ok=GetNextEvent(everyEvent,&ev);
  183. int where=FindWindow(ev.where,&win);
  184. if (ev.what == keyDown && collect && mode != GFX){
  185.      SetCtlValue(bar,GetCtlMax(bar));
  186.      redraw(numlines_ -  (GetCtlMax(bar) - GetCtlValue(bar)) - PAGELINES);
  187.      }
  188. if ((ev.what == keyDown) &&
  189.     (ev.modifiers &  cmdKey) &&
  190.     (toupper((char)(ev.message & charCodeMask)) == 'Q')  )
  191.          return -1;
  192. if (( ev.what == keyDown ) && collect && mode == GFX){
  193.      textmode();
  194.      process_char((char)(ev.message & charCodeMask));}
  195. if (ev.what == mouseDown && !disablescrollback && where ==inContent & mode == TEXT){
  196.         SelectWindow(win);
  197.         GlobalToLocal(&ev.where);
  198.          switch (FindControl(ev.where,win,&ctrl)){
  199.            case inThumb:
  200.         TrackControl(ctrl,ev.where,nil);
  201.             break;
  202.         case inUpButton:
  203. #if defined(powerc) || defined(__powerc)
  204.       {  
  205.       ControlActionUPP caupp= NewControlActionProc( scroll);
  206.       TrackControl (ctrl, ev.where, caupp);
  207.       }
  208. #else
  209.         TrackControl(ctrl,ev.where,scroll);
  210. #endif
  211.          break;
  212.         case inPageUp:
  213.            SetCtlValue(bar,GetCtlValue(bar) - 10);
  214.          break;
  215.         case inDownButton:
  216. #if defined(powerc) || defined(__powerc)
  217.       {  
  218.       ControlActionUPP caupp= NewControlActionProc( scroll);
  219.       TrackControl (ctrl, ev.where, caupp);
  220.       }
  221. #else
  222.          TrackControl(ctrl,ev.where,scroll);
  223. #endif
  224.          break;
  225.         case inPageDown:
  226.             SetCtlValue(bar,GetCtlValue(bar) + 10);
  227.          break;
  228.         default:
  229.          if (collect && mode == TEXT){
  230.             GetMouse(&MouseLoc);
  231.             cy = (int)((double)MouseLoc.v / (double)(LINEDEPTH)) +
  232.                  (numlines_ - (GetCtlMax(bar) - GetCtlValue(bar))
  233.                    - PAGELINES + 1);
  234.             for (i=0;i<strlen(lines[cy%SCROLLLINES]);++i)
  235.                  if ((lines[cy%SCROLLLINES])[i] == '(' ||
  236.                      (lines[cy%SCROLLLINES])[i] == '('   )
  237.                       (lines[cy%SCROLLLINES])[i]=' ';
  238.             sscanf(lines[cy%SCROLLLINES]," %[0-9a-zA-Z]",pasteword);
  239.               SetCtlValue(bar,GetCtlMax(bar));
  240.               redraw(numlines_ -  (GetCtlMax(bar) - GetCtlValue(bar)) - PAGELINES);
  241.             for (i=0;i<strlen(pasteword);++i)
  242.                  process_char(pasteword[i]);
  243.             process_char(0x0d);
  244.             }
  245.  
  246.             break;
  247.            }
  248.     redraw(numlines_ -  (GetCtlMax(bar) - GetCtlValue(bar)) - PAGELINES);
  249.     if (GetCtlMax(bar) == GetCtlValue(bar)){
  250.         macflush();
  251.            numlines_--;}
  252.     }
  253.  
  254. else if (ev.what == activateEvt)
  255.     InvalRect(&win->portRect);
  256.   else if (ev.what == updateEvt && mode == TEXT){
  257.      BeginUpdate(textWindow);
  258.     lasttop=100000;
  259.     redraw(numlines_ -  (GetCtlMax(bar) - GetCtlValue(bar)) - PAGELINES);
  260.     DrawControls(textWindow);
  261.      EndUpdate(textWindow);
  262.     }
  263.  
  264. else if (ev.what == mouseDown && where == inSysWindow)
  265.     SystemClick(&ev,win);
  266. else if (ev.what == mouseDown && where == inDrag) {
  267.     DragWindow(win,ev.where,&rect);}
  268.     
  269. else if (ev.what == mouseDown  && where == inGoAway)
  270.      return (win == gfxWindow ? 1: -1);
  271.  
  272. if (ev.what == mouseDown && where == inMenuBar){
  273.     menu=MenuSelect(ev.where);
  274.     menuitem = LoWord(menu);
  275.     menuid   = HiWord(menu);
  276. if (menuid == 2 && menuitem == 1)
  277.         return -1;
  278. if (menuid == 1){
  279.     GetPort(&savePort);
  280.     GetItem(appleMenu, menuitem, name);
  281.     OpenDeskAcc(name);
  282.     SetPort(savePort);}
  283.  
  284.     }
  285. else if (collect && mode == TEXT && (ev.what == keyDown))
  286.        process_char((char)(ev.message & charCodeMask));
  287.     
  288. return 1;
  289. }
  290.  
  291.  
  292. void macgets(s)
  293. char *s;
  294. {
  295. int status;
  296. collect=true;
  297. if (mode == GFX){
  298.   do {status=handleevent();} /* loop until this is false, or hit cr  */
  299.      while (collect && status);
  300.  
  301. if (status<= 0) process_window_closure(status);
  302.  
  303.  }
  304.  
  305. else {
  306.     macflush();               /* flush any waiting output (prompt?)   */
  307.     numlines_--;
  308.     inputcount=0;
  309.     collect=true;              /* tell the event loop to colect chars  */
  310.     do {status=handleevent();} /* loop until this is false, or hit cr  */
  311.        while (collect&&(status>0));
  312.     if (status<= 0) process_window_closure(status);
  313.     inputs[inputcount]=0;
  314.     strcpy(s,inputs);
  315.     macprintf("\n");
  316.     }
  317. }
  318.  
  319. int macscanf(char *s,...)
  320. {
  321. int i;
  322. char buf[256];
  323. void *p[10];
  324. va_list args;
  325. gets(buf);
  326.  
  327. va_start(args,s);
  328. for (i=0;i<10;++i)
  329.     p[i]=va_arg(args,void *);
  330. va_end(args);
  331. return sscanf(buf,s,p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8],p[9]);
  332. }
  333.  
  334. void macputs(s)
  335. char *s;
  336. {
  337. macprintf("%s\n",s);
  338. }
  339.  
  340. macputchar(c)
  341. char c;
  342. {
  343. macprintf("%c",c);
  344. }
  345.  
  346. void macprintf(char *s,...)
  347. {
  348. char buf[256];
  349.  
  350. va_list args;
  351. int i;
  352. if (mode == GFX)
  353.      return;
  354. if (strcmp(s,"\033[2J\033[H") ==0)
  355.      return;
  356. disablescrollback=1;
  357. va_start(args,s);
  358. vsprintf(buf,s,args);
  359. va_end(args);
  360. queryevent();
  361. SetPort(textWindow);
  362. MoveTo(cursorx,cursory);
  363. for (i=0;i<strlen(buf);++i){
  364.     if (isprint(buf[i]))
  365.         line[linectr++]=buf[i];    
  366.     else if (buf[i] == '\n'){
  367.         macflush();
  368.         linectr=0;
  369.         macnewline();
  370.         }
  371.     }
  372.     disablescrollback=0;
  373. }
  374.  
  375. macflush()
  376. {
  377. line[linectr]=0;
  378. if ((memptr+strlen(line) +1) > SCROLLMEM)
  379.      memptr=0;
  380.  
  381. lines[(numlines_)%SCROLLLINES]=&memory[(numlines_%SCROLLLINES)*SCROLLCOLUMNS];
  382. strcpy(lines[(numlines_++)%SCROLLLINES],line);
  383. MoveTo(0,cursory);
  384. putstring(line);
  385. }
  386.  
  387. macclear()
  388. {
  389. cursorx=0;
  390. cursory=0;
  391. EraseRect(&textrect);
  392. }
  393.  
  394. macnewline()
  395. {
  396. int i;
  397. cursorx=0;
  398. cursory+=LINEDEPTH;
  399. if (cursory >  260  ){
  400.     cursory-=LINEDEPTH;}
  401. MoveTo(cursorx,cursory);
  402.  SetCtlMax(bar,((numlines_ > SCROLLLINES ) ? SCROLLLINES  :
  403.                (numlines_ )) - PAGELINES);
  404. SetCtlValue(bar,GetCtlMax(bar));
  405.  redraw(numlines_ -  (GetCtlMax(bar) - GetCtlValue(bar)) - PAGELINES);
  406.  
  407. }
  408.  
  409.  
  410. redraw(pos)
  411. int pos;
  412. {
  413. int i,j,y=0;
  414. int lastbot = lasttop+pos;
  415. int delta   = pos-lasttop;
  416. int delta2  = lasttop-pos;
  417. int lbound  = pos;
  418. int ubound  = pos+PAGELINES;
  419. int tmpx    = cursorx;
  420. int tmpy    = cursory;
  421. if (numlines_ < PAGELINES)
  422.     delta=delta2=10000;
  423. textmode();
  424. pos = (pos < 0 ? 0 : pos);
  425. if (delta >= 0 && delta < SCROLLLINES ){
  426.     ScrollRect(&textrect,0,-delta*LINEDEPTH,rgn);
  427.     lbound = pos+PAGELINES-delta;
  428.     }
  429. else if (delta2 > 0 && delta2 < SCROLLLINES ){
  430.     ScrollRect(&textrect,0,delta2*LINEDEPTH,rgn);
  431.     ubound=delta2+pos;
  432.  
  433. }
  434.  
  435. else if (numlines_ >= PAGELINES)
  436.      EraseRect(&textrect);
  437. if (numlines_ == ubound)
  438.      ubound--;
  439. for (i=pos;i<pos-1+((PAGELINES < numlines_) ? numlines_ : PAGELINES);++i){
  440.     MoveTo(0,y);
  441.     if (i>= lbound && i<= ubound)
  442.         putstring(lines[i%SCROLLLINES]);
  443.     y+=LINEDEPTH;
  444.     
  445.  }
  446.  MoveTo(0,y);
  447.  y+=LINEDEPTH;
  448. lasttop = pos;
  449. MoveTo(tmpx,tmpy);
  450. }
  451.  
  452. putstring(string)
  453. char *string;
  454. {
  455. char buf[256];
  456. strcpy(buf+1,string);
  457. buf[0]=strlen(string);
  458. DrawString((ConstStr255Param)buf);
  459. cursorx+=StringWidth((ConstStr255Param)buf);
  460. }
  461.  
  462. textmode()
  463. {
  464. SetPort(textWindow);
  465. SelectWindow(textWindow);
  466. ShowWindow(textWindow);
  467. HideWindow(gfxWindow);
  468. mode = TEXT;
  469. }
  470.  
  471. gfxmode()
  472. {
  473. int status,ok;
  474. EventRecord ev;
  475. char c;
  476.  
  477. SetPort(gfxWindow);
  478. ShowWindow(gfxWindow);
  479. HideWindow(textWindow);
  480. SelectWindow(gfxWindow);
  481. mode = GFX;
  482. }
  483.  
  484. pascal void scroll(c,p)
  485. ControlHandle c;
  486. int p;
  487. {
  488. int direction=((p == inDownButton) ? 1 : (p ==  0)  ? 0 : -1);
  489. SetCtlValue(bar,GetCtlValue(bar) + direction);
  490. /* redraw(numlines_ -  (GetCtlMax(bar) - GetCtlValue(bar)) - PAGELINES);
  491. */
  492. }
  493.  
  494.  process_char(c)
  495. char c;
  496. {
  497. Rect drect;
  498.  
  499. if (isprint(c)){
  500.         inputs[inputcount++]=c;
  501.         line[linectr++]=c;
  502.         if (GetCtlValue(bar) == GetCtlMax(bar) && mode==TEXT) {
  503.         macflush();
  504.         numlines_--;}
  505.         }
  506.     else{
  507.     switch (c){
  508.         case 0x03:     /* if it's the enter key */
  509.         case 0x0d:     /* or the return key     */
  510.             collect=false; /* stop collecting chars */
  511.             break;
  512.         case 0x08: /* delete */
  513.         case 0x1c: /* or back space */
  514.             if (inputcount > 0 && mode == TEXT) {
  515.                 cursorx-=CharWidth(inputs[--inputcount]);
  516.                 MoveTo(cursorx,cursory);
  517.                 inputs[inputcount]=0;
  518.                  drect.top=cursory-LINEDEPTH;
  519.                  drect.left=0;
  520.                  drect.bottom=cursory+3;
  521.                  drect.right=344;
  522.                  EraseRect(&drect);
  523.                  line[--linectr]=0;
  524.                 if (GetCtlValue(bar) == GetCtlMax(bar)){
  525.                 macflush();
  526.                 numlines_--;}
  527.                 }
  528.             break;
  529.         default:
  530.             break;}
  531.       }
  532. }
  533.  
  534. void fixmacfile(filename)
  535. char *filename;
  536. {
  537. OSErr retcode;
  538. FInfo  fndrinfo;
  539. char filename1[100];
  540. char filename2[100];
  541. strcpy(filename1,filename);
  542. strcpy(filename2,filename);
  543. retcode=GetFInfo(CtoPstr(filename1),0,&fndrinfo);
  544. fndrinfo.fdType='TEXT';
  545. fndrinfo.fdCreator='MSWD';
  546. retcode=SetFInfo(CtoPstr(filename2),0,&fndrinfo);
  547. }
  548.  
  549.